package twitter

import (
	"encoding/json"
	uuid2 "github.com/pborman/uuid"
	"github.com/zeromicro/go-zero/core/syncx"
	"math/rand"
	"time"
)

type TokenData struct {
	XClientUUID            string            `json:"uuid"`
	XTwitterClientDeviceID string            `json:"deviceId"`
	XTwitterClientAdID     string            `json:"adId"`
	Cookie                 string            `json:"cookie"`
	XGuestToken            string            `json:"guestToken"`
	XTwitterClientAppSetID string            `json:"appSetId"`
	Authorization          string            `json:"authorization"`
	XRateLimitLimit        int               `json:"rateLimit"`     //上限
	XRateLimitRemaining    int               `json:"rateRemaining"` //剩余次数
	XRateLimitReset        int               `json:"rateReset"`     //下次重置时间
	Duration               int               `json:"duration"`
	ObtainTime             time.Time         `json:"obtainTime"`     //从api取得时间
	IsBadGuestToken        *syncx.AtomicBool `json:"isBad"`          //guest token 已过期
	IsRefreshToken         *syncx.AtomicBool `json:"IsRefreshToken"` //是否正常刷新token（包含步骤一和步骤二）
	IsExpiredFlowToken     *syncx.AtomicBool `json:"isExpired"`      //flow_token 已被消费需要重新获取
	IsTokenInvalid         *syncx.AtomicBool `json:"isTokenInvalid"` //token是否失效(表示需要重新获取token，从步骤一开始获取)
}

func NewTwitterTokenData() *TokenData {
	// 基于时间生成随机uUid
	clientUUid := uuid2.New()
	//生成Client-DeviceID
	clientDeviceId := RandomString(16) //6ce90a417c1d3581
	return &TokenData{
		XTwitterClientDeviceID: clientDeviceId,
		XClientUUID:            clientUUid,
		XTwitterClientAdID:     "bd11b02a-46a0-4c02-91cc-" + RandomString(12),
		XTwitterClientAppSetID: "c189dddc-f4fe-2eb6-b694-23007f6c96b9",
		IsBadGuestToken:        syncx.ForAtomicBool(true),
		IsExpiredFlowToken:     syncx.ForAtomicBool(true),
		IsTokenInvalid:         syncx.ForAtomicBool(true),
		IsRefreshToken:         syncx.ForAtomicBool(true),
	}
}

var defaultLetters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")

func RandomString(n int) string {
	var letters = defaultLetters

	b := make([]rune, n)
	for i := range b {
		b[i] = letters[rand.Intn(len(letters))]
	}

	return string(b)
}

func (ib *TokenData) OutInterval() bool {
	//已用时间s
	usedSeconds := time.Now().Sub(ib.ObtainTime).Hours()
	//间隔时间s
	return usedSeconds > 2
}

// token过期
func (ib *TokenData) CheckIsExpired() bool {
	if ib.IsBadGuestToken.True() {
		return true
	}
	if ib.IsExpiredFlowToken.True() {
		return true
	}
	if ib.OutInterval() {
		return true
	}
	return false
}
func (ib *TokenData) ToString() string {
	marshal, err := json.Marshal(ib)
	if err != nil {
		return ""
	}
	return string(marshal)
}

// TokenResp  获取token响应内容
type TokenResp struct {
	TokenType    string `json:"token_type"`
	AccessToken  string `json:"access_token"`
	CookieString string `json:"cookie"`
}

func (ib *TokenResp) ToString() string {
	marshal, err := json.Marshal(ib)
	if err != nil {
		return ""
	}
	return string(marshal)
}

// TokenAndIpData TokenResp  获取token响应内容
type TokenAndIpData struct {
	TokenResp `json:"token_resp"`
	IpData    `json:"ip_data"`
}

// TokenAndIpPool  TokenResp  获取token响应内容
type TokenAndIpPool struct {
	TokenResp `json:"token_resp"`
	IpData    string `json:"ip_data"`
}

// GetHeaderParam 获取请求头信息
type GetHeaderParam struct {
}

// GuestTokenResp 获取guest token 响应
type GuestTokenResp struct {
	GuestToken string `json:"guest_token"`
}

// GuestTokenAndIpResp  获取guest token ip 响应
type GuestTokenAndIpResp struct {
	GuestToken string `json:"guest_token"`
	IpData     string `json:"ip_data"`
}

// GuestTokenAndIpData  获取guest token 响应
type GuestTokenAndIpData struct {
	GuestToken string `json:"guest_token"`
	IpData     `json:"ip_data"`
}

// FlowTokenResp 获取flow token 响应
type FlowTokenResp struct {
	FlowToken string `json:"flow_token"`
	Status    string `json:"status"`
}

// AttAndFlowTokenResp  获取flow token 响应 以及请求头
type AttAndFlowTokenResp struct {
	FlowToken string `json:"flow_token"`
	Status    string `json:"status"`
	Att       string `json:"att"`
}

func (ib *AttAndFlowTokenResp) ToString() string {
	marshal, err := json.Marshal(ib)
	if err != nil {
		return ""
	}
	return string(marshal)
}

// AttIpAndFlowTokenResp  获取flow token 响应 ip 以及请求头
type AttIpAndFlowTokenResp struct {
	AttAndFlowTokenResp `json:"att_and_flow_token_resp"`
	IpData              string `json:"ip_data"`
}

// NumberVerifyReqBody 号码请求判断请求body
type NumberVerifyReqBody struct {
	FlowToken     string `json:"flow_token"`
	SubtaskInputs []struct {
		EnterText struct {
			SuggestionId interface{} `json:"suggestion_id"`
			Text         string      `json:"text"`
			Link         string      `json:"link"`
		} `json:"enter_text"`
		SubtaskId string `json:"subtask_id"`
	} `json:"subtask_inputs"`
	SubtaskVersions `json:"subtask_versions"`
}

// NumberSubtaskVersions 号码请求判断请求body
type NumberSubtaskVersions struct {
	GenericUrt                       int `json:"generic_urt"`
	Standard                         int `json:"standard"`
	OpenHomeTimeline                 int `json:"open_home_timeline"`
	AppLocaleUpdate                  int `json:"app_locale_update"`
	EnterDate                        int `json:"enter_date"`
	EmailVerification                int `json:"email_verification"`
	EnterPassword                    int `json:"enter_password"`
	EnterText                        int `json:"enter_text"`
	OneTap                           int `json:"one_tap"`
	Cta                              int `json:"cta"`
	SingleSignOn                     int `json:"single_sign_on"`
	FetchPersistedData               int `json:"fetch_persisted_data"`
	EnterUsername                    int `json:"enter_username"`
	WebModal                         int `json:"web_modal"`
	FetchTemporaryPassword           int `json:"fetch_temporary_password"`
	MenuDialog                       int `json:"menu_dialog"`
	SignUpReview                     int `json:"sign_up_review"`
	InterestPicker                   int `json:"interest_picker"`
	UserRecommendationsUrt           int `json:"user_recommendations_urt"`
	InAppNotification                int `json:"in_app_notification"`
	SignUp                           int `json:"sign_up"`
	TypeaheadSearch                  int `json:"typeahead_search"`
	UserRecommendationsList          int `json:"user_recommendations_list"`
	CtaInline                        int `json:"cta_inline"`
	ContactsLiveSyncPermissionPrompt int `json:"contacts_live_sync_permission_prompt"`
	ChoiceSelection                  int `json:"choice_selection"`
	JsInstrumentation                int `json:"js_instrumentation"`
	AlertDialogSuppressClientEvents  int `json:"alert_dialog_suppress_client_events"`
	PrivacyOptions                   int `json:"privacy_options"`
	TopicsSelector                   int `json:"topics_selector"`
	WaitSpinner                      int `json:"wait_spinner"`
	TweetSelectionUrt                int `json:"tweet_selection_urt"`
	EndFlow                          int `json:"end_flow"`
	SettingsList                     int `json:"settings_list"`
	OpenExternalLink                 int `json:"open_external_link"`
	PhoneVerification                int `json:"phone_verification"`
	SecurityKey                      int `json:"security_key"`
	SelectBanner                     int `json:"select_banner"`
	UploadMedia                      int `json:"upload_media"`
	Web                              int `json:"web"`
	AlertDialog                      int `json:"alert_dialog"`
	OpenAccount                      int `json:"open_account"`
	ActionList                       int `json:"action_list"`
	EnterPhone                       int `json:"enter_phone"`
	OpenLink                         int `json:"open_link"`
	ShowCode                         int `json:"show_code"`
	UpdateUsers                      int `json:"update_users"`
	CheckLoggedInAccount             int `json:"check_logged_in_account"`
	EnterEmail                       int `json:"enter_email"`
	SelectAvatar                     int `json:"select_avatar"`
	LocationPermissionPrompt         int `json:"location_permission_prompt"`
	NotificationsPermissionPrompt    int `json:"notifications_permission_prompt"`
}

// FlowTokenReqBody 获取flow token 请求body
type FlowTokenReqBody struct {
	FlowToken     interface{} `json:"flow_token"`
	InputFlowData struct {
		CountryCode interface{} `json:"country_code"`
		FlowContext struct {
			ReferrerContext struct {
				ReferralDetails string `json:"referral_details"`
				ReferrerUrl     string `json:"referrer_url"`
			} `json:"referrer_context"`
			StartLocation struct {
				Location string `json:"location"`
			} `json:"start_location"`
		} `json:"flow_context"`
		RequestedVariant interface{} `json:"requested_variant"`
		TargetUserId     int         `json:"target_user_id"`
	} `json:"input_flow_data"`
	SubtaskVersions `json:"subtask_versions"`
}

// SubtaskVersions 获取flow token 请求body
type SubtaskVersions struct {
	GenericUrt                       int `json:"generic_urt"`
	Standard                         int `json:"standard"`
	OpenHomeTimeline                 int `json:"open_home_timeline"`
	AppLocaleUpdate                  int `json:"app_locale_update"`
	EnterDate                        int `json:"enter_date"`
	EmailVerification                int `json:"email_verification"`
	EnterPassword                    int `json:"enter_password"`
	EnterText                        int `json:"enter_text"`
	OneTap                           int `json:"one_tap"`
	Cta                              int `json:"cta"`
	SingleSignOn                     int `json:"single_sign_on"`
	FetchPersistedData               int `json:"fetch_persisted_data"`
	EnterUsername                    int `json:"enter_username"`
	WebModal                         int `json:"web_modal"`
	FetchTemporaryPassword           int `json:"fetch_temporary_password"`
	MenuDialog                       int `json:"menu_dialog"`
	SignUpReview                     int `json:"sign_up_review"`
	InterestPicker                   int `json:"interest_picker"`
	UserRecommendationsUrt           int `json:"user_recommendations_urt"`
	InAppNotification                int `json:"in_app_notification"`
	SignUp                           int `json:"sign_up"`
	TypeaheadSearch                  int `json:"typeahead_search"`
	UserRecommendationsList          int `json:"user_recommendations_list"`
	CtaInline                        int `json:"cta_inline"`
	ContactsLiveSyncPermissionPrompt int `json:"contacts_live_sync_permission_prompt"`
	ChoiceSelection                  int `json:"choice_selection"`
	JsInstrumentation                int `json:"js_instrumentation"`
	AlertDialogSuppressClientEvents  int `json:"alert_dialog_suppress_client_events"`
	PrivacyOptions                   int `json:"privacy_options"`
	TopicsSelector                   int `json:"topics_selector"`
	WaitSpinner                      int `json:"wait_spinner"`
	TweetSelectionUrt                int `json:"tweet_selection_urt"`
	EndFlow                          int `json:"end_flow"`
	SettingsList                     int `json:"settings_list"`
	OpenExternalLink                 int `json:"open_external_link"`
	PhoneVerification                int `json:"phone_verification"`
	SecurityKey                      int `json:"security_key"`
	SelectBanner                     int `json:"select_banner"`
	UploadMedia                      int `json:"upload_media"`
	Web                              int `json:"web"`
	AlertDialog                      int `json:"alert_dialog"`
	OpenAccount                      int `json:"open_account"`
	ActionList                       int `json:"action_list"`
	EnterPhone                       int `json:"enter_phone"`
	OpenLink                         int `json:"open_link"`
	ShowCode                         int `json:"show_code"`
	UpdateUsers                      int `json:"update_users"`
	CheckLoggedInAccount             int `json:"check_logged_in_account"`
	EnterEmail                       int `json:"enter_email"`
	SelectAvatar                     int `json:"select_avatar"`
	LocationPermissionPrompt         int `json:"location_permission_prompt"`
	NotificationsPermissionPrompt    int `json:"notifications_permission_prompt"`
}

// NumberVerifyResp 验证号码返回结果
type NumberVerifyResp struct {
	FlowToken string              `json:"flow_token,omitempty"`
	Status    string              `json:"status,omitempty"`
	Errors    []NumberVerifyError `json:"errors,omitempty"`

	Subtasks []struct {
		SubtaskId string `json:"subtask_id"`
		/*EnterText struct {
			PrimaryText struct {
				Text     string        `json:"text"`
				Entities []interface{} `json:"entities"`
			} `json:"primary_text"`
			SecondaryText struct {
				Text     string        `json:"text"`
				Entities []interface{} `json:"entities"`
			} `json:"secondary_text"`
			HintText               string `json:"hint_text"`
			Multiline              bool   `json:"multiline"`
			AutoCapitalizationType string `json:"auto_capitalization_type"`
			AutoCorrectionEnabled  bool   `json:"auto_correction_enabled"`
			KeyboardType           string `json:"keyboard_type"`
			NextLink               struct {
				LinkType string `json:"link_type"`
				LinkId   string `json:"link_id"`
				Label    string `json:"label"`
			} `json:"next_link"`
		} `json:"enter_text"`
		SubtaskBackNavigation string `json:"subtask_back_navigation"`
		*/
	} `json:"subtasks"`
}

func (tb *NumberVerifyResp) ToString() string {
	b, _ := json.Marshal(tb)
	return string(b)
}

// NumberVerifyError 错误返回信息
type NumberVerifyError struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
}

// IpResp 获取代理ip响应
type IpResp struct {
	Code    int      `json:"code"`
	Data    []IpData `json:"data"`
	Message string   `json:"message"`
}

// IpData 每个ip信息
type IpData struct {
	Duration int    `json:"duration"`
	Country  string `json:"country"`
	Port     string `json:"port"`
	Ip       string `json:"ip"`
	Tip      string `json:"tip"`
}
